<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="./lib/dist/include-openlayers-local.js"></script>
    <style>
      #map {
        width: 100%;
        height: 95%;
        position: absolute;
      }

      #menu {
        float: left;
        position: absolute;
        bottom: 10px;
        left: 10px;
        z-index: 2000;
      }

      .checkbox {
        left: 20px;
      }
      /**
        * 提示框的样式信息
        */
      .tooltip {
        position: relative;
        background: rgba(0, 0, 0, 0.5);
        border-radius: 4px;
        color: white;
        padding: 4px 8px;
        opacity: 0.7;
        white-space: nowrap;
      }

      .tooltip-measure {
        opacity: 1;
        font-weight: bold;
      }

      .tooltip-static {
        background-color: #ffcc33;
        color: black;
        border: 1px solid white;
      }
    </style>
  </head>
  <body>
    <div id="map">
      <div id="menu">
        <label>Geometry type &nbsp;</label>
        <select id="type">
          <option value="length">Length</option>
          <option value="area">Area</option>
        </select>
        <label class="checkbox"><input type="checkbox" id="geodesic" />use geodesic measures</label>
      </div>
      <div id="arealength"></div>
    </div>
    <script>
      const gaodeMapLayer = new ol.layer.Tile({
        title: '高德地图',
        source: new ol.source.XYZ({
          url: 'http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}',
          wrapX: false
        })
      })
      const map = new ol.Map({
        target: 'map',
        view: new ol.View({
          // projection: 'EPSG:4326',
          center: [11635617.0761, 3552110.0444],
          zoom: 6
        }),
        layers: [gaodeMapLayer]
      })
      //加载测量的绘制矢量层
      var source = new ol.source.Vector() //图层数据源
      var vector = new ol.layer.Vector({
        source: source,
        style: new ol.style.Style({
          //图层样式
          fill: new ol.style.Fill({
            color: 'rgba(255, 255, 255, 0.2)' //填充颜色
          }),
          stroke: new ol.style.Stroke({
            color: '#ffcc33', //边框颜色
            width: 2 // 边框宽度
          }),
          image: new ol.style.Circle({
            radius: 7,
            fill: new ol.style.Fill({
              color: '#ffcc33'
            })
          })
        })
      })
      map.addLayer(vector)
      var sketch
      var geodesicCheckbox = document.getElementById('geodesic') 
      var typeSelect = document.getElementById('type') 
      var draw
      function addInteraction(type) {
        var type = typeSelect.value == 'area' ? 'Polygon' : 'LineString'
        draw = new ol.interaction.Draw({
          source: source, //测量绘制层数据源
          type: type, //几何图形类型
          style: new ol.style.Style({
            //绘制几何图形的样式
            fill: new ol.style.Fill({
              color: 'rgba(255, 255, 255, 0.2)'
            }),
            stroke: new ol.style.Stroke({
              color: 'rgba(0, 0, 0, 0.5)',
              lineDash: [10, 10],
              width: 2
            }),
            image: new ol.style.Circle({
              radius: 5,
              stroke: new ol.style.Stroke({
                color: 'rgba(0, 0, 0, 0.7)'
              }),
              fill: new ol.style.Fill({
                color: 'rgba(255, 255, 255, 0.2)'
              })
            })
          })
        })
        map.addInteraction(draw)

        createpopu()
        var listener
        draw.on(
          'drawstart',
          function (evt) {
            // set sketch
            sketch = evt.feature //绘制的要素
            var tooltipCoord = evt.coordinate // 绘制的坐标
            //绑定change事件，根据绘制几何类型得到测量长度值或面积值，并将其设置到测量工具提示框中显示
            listener = sketch.getGeometry().on('change', function (evt) {
              var geom = evt.target //绘制几何要素
              var output
              if (geom instanceof ol.geom.Polygon) {
                output = formatArea(geom) //面积值
                tooltipCoord = geom.getInteriorPoint().getCoordinates() //坐标
              } else if (geom instanceof ol.geom.LineString) {
                output = formatLength(geom) //长度值
                tooltipCoord = geom.getLastCoordinate() //坐标
              }
              measureTooltipElement.innerHTML = output
              measureTooltip.setPosition(tooltipCoord)
            })
          },
          this
        )
        //绑定交互绘制工具结束绘制的事件
        draw.on(
          'drawend',
          function (evt) {
            measureTooltipElement.className = 'tooltip tooltip-static'
            measureTooltip.setOffset([0, -7])
            sketch = null
            createpopu()
            ol.Observable.unByKey(listener)
          },
          this
        )
      }
      var measureTooltipElement
      var measureTooltip
      function createpopu() {
        measureTooltipElement = document.createElement('div')
        measureTooltipElement.className = 'tooltip tooltip-measure'
        measureTooltip = new ol.Overlay({
          element: measureTooltipElement,
          offset: [0, -15],
          positioning: 'bottom-center'
        })
        map.addOverlay(measureTooltip)
      }

      typeSelect.onchange = function (e) {
        map.removeInteraction(draw) //移除绘制图形
        addInteraction() //添加绘图进行测量
      }
      var formatLength = function (line) {
        var length
        var sphere = new ol.Sphere()
        if (geodesicCheckbox.checked) {
          //若使用测地学方法测量
          var sourceProj = map.getView().getProjection() //地图数据源投影坐标系
          length = sphere.getLength(line, { projection: sourceProj, radius: 6378137 })
        } else {
          length = Math.round(line.getLength() * 100) / 100 //直接得到线的长度
        }
        var output
        if (length > 100) {
          output = Math.round((length / 1000) * 100) / 100 + ' ' + 'km' //换算成KM单位
        } else {
          output = Math.round(length * 100) / 100 + ' ' + 'm' //m为单位
        }
        return output //返回线的长度
      }

      var formatArea = function (polygon) {
        var area
        var sphere = new ol.Sphere()
        if (geodesicCheckbox.checked) {
          //若使用测地学方法测量
          var sourceProj = map.getView().getProjection() //地图数据源投影坐标系
          var geom = polygon.clone().transform(sourceProj, 'EPSG:4326') //将多边形要素坐标系投影为EPSG:4326
          area = Math.abs(sphere.getArea(geom, { projection: sourceProj, radius: 6378137 })) //获取面积
        } else {
          area = polygon.getArea() //直接获取多边形的面积
        }
        var output
        if (area > 10000) {
          output = Math.round((area / 1000000) * 100) / 100 + ' ' + 'km<sup>2</sup>' //换算成KM单位
        } else {
          output = Math.round(area * 100) / 100 + ' ' + 'm<sup>2</sup>' //m为单位
        }
        return output //返回多边形的面积
      }

      addInteraction()
    </script>
  </body>
</html>
